import type { GreasyForkElements } from '../../../../../../types/constants/personalization/greasy_fork'
import type { ThemeType } from '../../../../../../types/interfaces'
import { OthersThemeService } from '../../../../../../lib/abstract'
import { ElementManager } from '../../../../../../lib/element_manager'
import { PageHandler } from '../../../../../../lib/page_handler'
import {
  getGreasyForkPageCategory,
  GreasyForkPageType,
} from '../../../../../../lib/page_handler/platform/greasyfork/types'
import {
  AppStyleCollections,
  BODY_SELECTOR,
  BodyClasses,
  logger,
  MODULE_CONFIG,
  PLATFORM_PAGE_TYPES,
  PROJECT_PREFIX,
  SUPPORTED_PLATFORMS,
} from '../../../../../../types/constants'
import { getElementSelector } from '../../../../../../types/constants/personalization/common'
import { IndexPage } from './greasy_fork/page'
import { NotFoundPage } from './greasy_fork/page/404'
import { CommonPage } from './greasy_fork/page/common'
import { DiscussionsPage } from './greasy_fork/page/discussions'
import { DiscussionsDetailPage } from './greasy_fork/page/discussions/discussions_detail'
import { DiscussionsDevelopmentPage } from './greasy_fork/page/discussions/discussions_development'
import { DiscussionsGreasyForkPage } from './greasy_fork/page/discussions/discussions_greasyfork'
import { DiscussionsNewPage } from './greasy_fork/page/discussions/discussions_new'
import { DiscussionsNoScriptPage } from './greasy_fork/page/discussions/discussions_no_script'
import { DiscussionsRequestsPage } from './greasy_fork/page/discussions/discussions_requests'
import { DiscussionsScriptPage } from './greasy_fork/page/discussions/discussions_script'
import { HelpPage } from './greasy_fork/page/help'
import { AllowedMarkupPage } from './greasy_fork/page/help/allowed_markup'
import { CodeRulesPage } from './greasy_fork/page/help/code_rules'
import { ContactPage } from './greasy_fork/page/help/contact'
import { CreditsPage } from './greasy_fork/page/help/credits'
import { ExternalScriptsPage } from './greasy_fork/page/help/external_scripts'
import { InstallingUserScriptsPage } from './greasy_fork/page/help/installing_user_scripts'
import { InstallingUserStylesPage } from './greasy_fork/page/help/installing_user_styles'
import { MetaKeysPage } from './greasy_fork/page/help/meta_keys'
import { PrivacyPage } from './greasy_fork/page/help/privacy'
import { RewritingPage } from './greasy_fork/page/help/rewriting'
import { UserJsConversionsPage } from './greasy_fork/page/help/user_js_conversions'
import { WritingUserScriptsPage } from './greasy_fork/page/help/writing_user_scripts'
import { LibrariesPage } from './greasy_fork/page/libraries'
import { ModeratorActionsPage } from './greasy_fork/page/moderator_actions'
import { ReportsPage } from './greasy_fork/page/reports'
import { ReportNewPage } from './greasy_fork/page/reports/reports_new'
import { ScriptAdminPage } from './greasy_fork/page/script/admin'
import { BySitePage } from './greasy_fork/page/script/by_site'
import { CodePage } from './greasy_fork/page/script/code'
import { ScriptDeletePage } from './greasy_fork/page/script/delete'
import { ScriptDeletedPage } from './greasy_fork/page/script/deleted'
import { ScriptDerivativesPage } from './greasy_fork/page/script/derivatives'
import { FeedbackPage } from './greasy_fork/page/script/feedback'
import { DiscussionPage } from './greasy_fork/page/script/feedback/discussion'
import { InfoPage } from './greasy_fork/page/script/info'
import { ScriptLockAppealsPage } from './greasy_fork/page/script/lock_appeals'
import { VersionsPage } from './greasy_fork/page/script/versions'
import { DiffPage } from './greasy_fork/page/script/versions/diff'
import { ScriptVersionsNewPage } from './greasy_fork/page/script/versions_new'
import { ScriptListPage } from './greasy_fork/page/script_list'
import { SearchPage } from './greasy_fork/page/search'
import { UsersPage } from './greasy_fork/page/users'
import { UserConversationsPage } from './greasy_fork/page/users/conversations'
import { DeleteInfoPage } from './greasy_fork/page/users/delete_info'
import { EditPage } from './greasy_fork/page/users/edit'
import { EditSignInPage } from './greasy_fork/page/users/edit_sign_in'
import { ImportPage } from './greasy_fork/page/users/import'
import { NewCssPage } from './greasy_fork/page/users/new_css'
import { NewJsPage } from './greasy_fork/page/users/new_js'
import { NotificationSettingsPage } from './greasy_fork/page/users/notification_settings'
import { NotificationsPage } from './greasy_fork/page/users/notifications'
import { PasswordEditPage } from './greasy_fork/page/users/password_edit'
import { PasswordNewPage } from './greasy_fork/page/users/password_new'
import { SetsNewPage } from './greasy_fork/page/users/sets_new'
import { SignInPage } from './greasy_fork/page/users/sign_in'
import { SignUpPage } from './greasy_fork/page/users/sign_up'
import { UserPage } from './greasy_fork/page/users/user'
import { WebhookInfoPage } from './greasy_fork/page/users/webhook'

/**
 * 页面处理器
 */
const PAGE_HANDLERS: Partial<Record<GreasyForkPageType, any>> = {
  [GreasyForkPageType.SIGN_IN]: SignInPage,
  [GreasyForkPageType.SIGN_UP]: SignUpPage,
  [GreasyForkPageType.PASSWORD_NEW]: PasswordNewPage,
  [GreasyForkPageType.PASSWORD_EDIT]: PasswordEditPage,
  [GreasyForkPageType.INDEX]: IndexPage,
  [GreasyForkPageType.SCRIPT_LIST]: ScriptListPage,
  [GreasyForkPageType.BY_SITE]: BySitePage,
  [GreasyForkPageType.SCRIPT_DELETED]: ScriptDeletedPage,
  [GreasyForkPageType.SCRIPT_LOCK_APPEALS]: ScriptLockAppealsPage,
  [GreasyForkPageType.SCRIPT_INFO]: InfoPage,
  [GreasyForkPageType.SCRIPT_CODE]: CodePage,
  [GreasyForkPageType.SCRIPT_VERSIONS]: VersionsPage,
  [GreasyForkPageType.SCRIPT_FEEDBACK]: FeedbackPage,
  [GreasyForkPageType.SCRIPT_DERIVATIVES]: ScriptDerivativesPage,
  [GreasyForkPageType.SCRIPT_VERSIONS_NEW]: ScriptVersionsNewPage,
  [GreasyForkPageType.SCRIPT_DELETE]: ScriptDeletePage,
  [GreasyForkPageType.SCRIPT_ADMIN]: ScriptAdminPage,
  [GreasyForkPageType.DISCUSSIONS]: DiscussionsPage,
  [GreasyForkPageType.DISCUSSIONS_DEVELOPMENT]: DiscussionsDevelopmentPage,
  [GreasyForkPageType.DISCUSSIONS_GREASY_FORK]: DiscussionsGreasyForkPage,
  [GreasyForkPageType.DISCUSSIONS_NEW]: DiscussionsNewPage,
  [GreasyForkPageType.DISCUSSIONS_DETAIL]: DiscussionsDetailPage,
  [GreasyForkPageType.DISCUSSIONS_NO_SCRIPT]: DiscussionsNoScriptPage,
  [GreasyForkPageType.DISCUSSIONS_REQUESTS]: DiscussionsRequestsPage,
  [GreasyForkPageType.DISCUSSIONS_SCRIPT]: DiscussionsScriptPage,
  [GreasyForkPageType.SCRIPT_DISCUSSION]: DiscussionPage,
  [GreasyForkPageType.USER_PROFILE]: UserPage,
  [GreasyForkPageType.USER_CONVERSATIONS]: UserConversationsPage,
  [GreasyForkPageType.SCRIPT_DIFF]: DiffPage,
  [GreasyForkPageType.SEARCH]: SearchPage,
  [GreasyForkPageType.USERS]: UsersPage,
  [GreasyForkPageType.MODERATOR_ACTIONS]: ModeratorActionsPage,
  [GreasyForkPageType.REPORTS]: ReportsPage,
  [GreasyForkPageType.REPORTS_NEW]: ReportNewPage,
  [GreasyForkPageType.LIBRARIES]: LibrariesPage,
  [GreasyForkPageType.HELP]: HelpPage,
  [GreasyForkPageType.ALLOWED_MARKUP]: AllowedMarkupPage,
  [GreasyForkPageType.CODE_RULES]: CodeRulesPage,
  [GreasyForkPageType.CONTACT]: ContactPage,
  [GreasyForkPageType.CREDITS]: CreditsPage,
  [GreasyForkPageType.EXTERNAL_SCRIPTS]: ExternalScriptsPage,
  [GreasyForkPageType.INSTALLING_USER_SCRIPTS]: InstallingUserScriptsPage,
  [GreasyForkPageType.INSTALLING_USER_STYLES]: InstallingUserStylesPage,
  [GreasyForkPageType.META_KEYS]: MetaKeysPage,
  [GreasyForkPageType.PRIVACY]: PrivacyPage,
  [GreasyForkPageType.REWRITING]: RewritingPage,
  [GreasyForkPageType.USER_JS_CONVERSIONS]: UserJsConversionsPage,
  [GreasyForkPageType.WRITING_USER_SCRIPTS]: WritingUserScriptsPage,
  [GreasyForkPageType.NEW_JS]: NewJsPage,
  [GreasyForkPageType.NEW_CSS]: NewCssPage,
  [GreasyForkPageType.SETS_NEW]: SetsNewPage,
  [GreasyForkPageType.IMPORT]: ImportPage,
  [GreasyForkPageType.WEBHOOK_INFO]: WebhookInfoPage,
  [GreasyForkPageType.EDIT]: EditPage,
  [GreasyForkPageType.EDIT_SIGN_IN]: EditSignInPage,
  [GreasyForkPageType.NOTIFICATIONS]: NotificationsPage,
  [GreasyForkPageType.NOTIFICATION_SETTINGS]: NotificationSettingsPage,
  [GreasyForkPageType.DELETE_INFO]: DeleteInfoPage,
  [GreasyForkPageType.NOT_FOUND]: NotFoundPage,
}

/**
 * 主题服务测试链接
 */
export class GreasyForkThemeService extends OthersThemeService {
  readonly name: string = 'GreasyForkTheme'
  readonly platformPageType: string = PLATFORM_PAGE_TYPES.OTHERS.value
  private static instance: GreasyForkThemeService
  declare readonly elements: GreasyForkElements
  readonly wrapperSelector: string = BODY_SELECTOR
  private commonPage: CommonPage = CommonPage.getInstance()
  private scriptListPage: ScriptListPage = ScriptListPage.getInstance()
  private readonly pageHandler: PageHandler = PageHandler.getInstance()
  private elementManager: ElementManager = ElementManager.getInstance()
  private readonly currentPageType: GreasyForkPageType | 'default' = this.pageHandler.pages.greasyFork.pageType

  constructor() {
    super(SUPPORTED_PLATFORMS.GREASY_FORK)

    this.updateElementStylesForTheme()
    this.checkPageType(this.currentPageType)
    logger.info(`[${this.name}] 识别页面分类为：${getGreasyForkPageCategory(this.currentPageType as GreasyForkPageType)}`)
  }

  /**
   * 获取单例实例
   */
  static getInstance(): GreasyForkThemeService {
    if (!GreasyForkThemeService.instance) {
      GreasyForkThemeService.instance = new GreasyForkThemeService()
    }
    return GreasyForkThemeService.instance
  }

  /**
   * 批量初始化页面样式
   */
  updateElementStylesForTheme(): void {
    // 通用样式初始化
    this.commonPage.init()

    // 动态获取当前页面处理器并初始化
    const PageHandlerClass = PAGE_HANDLERS[this.currentPageType as GreasyForkPageType]
    if (PageHandlerClass) {
      PageHandlerClass.getInstance().init()
    }
    else {
      logger.warn(`未找到 ${this.currentPageType} 页面的处理器`)
    }
  }

  platformStyleVar(theme: ThemeType): string {
    return `
  --${PROJECT_PREFIX}-theme-result-border-primary: ${this.getColorValue(theme, 'resultBorderPrimary')};
  --${PROJECT_PREFIX}-theme-result-border-primary-hover: ${this.getColorValue(theme, 'resultBorderPrimaryHover')};
  `
  }

  getBaseStyles(_theme: ThemeType): string {
    const {
      CONTENT_CONTAINER,
      RESULT_CONTAINER,
      ARTICLE_CONTENT,
    } = this.elements

    const BACKGROUND_SELECTORS = [
      CONTENT_CONTAINER?.selector,
      getElementSelector(this.elements, 'COMMON_CONTAINER'),
    ].filter(Boolean).join(',')

    const BACKGROUND_RESET_SELECTORS = [
      RESULT_CONTAINER?.selector,
    ].filter(Boolean).join(',')

    const TEXT_COLOR_SELECTORS = [
      ARTICLE_CONTENT?.selector,
    ].filter(Boolean).join(',')

    // 生成 CSS 规则
    const styles = [
      BACKGROUND_SELECTORS && `
${BACKGROUND_SELECTORS} {
  background-color: var(--${PROJECT_PREFIX}-theme-bg-base) !important;
  line-height: 1.8;
}
    `,

      BACKGROUND_RESET_SELECTORS && `
${BACKGROUND_RESET_SELECTORS} {
  background-color: unset !important;
}
    `,
      TEXT_COLOR_SELECTORS && `
${TEXT_COLOR_SELECTORS} {
  color: var(${this.themeVarService.default.text.secondary}) !important;
}
    `,
    ].filter(Boolean).join('\n')

    return `
${styles}
`
  }

  getPageStyles(_theme: ThemeType): string {
    return `
${BODY_SELECTOR} { 
  padding: 0 !important;
  background-color: var(${this.themeVarService.default.background.base}) !important;
  
  .sidebarred, #user-discussions, #about-user  {
    padding: 20px !important;
  }
  
  #script-info, #about-user {
    margin-top: 0 !important;
  }
  
  #script-info {
    box-shadow: none !important;
    border: none !important;
  }
}

/* 移动端样式 */
${BODY_SELECTOR}.${BodyClasses.IS_MOBILE} {
  .width-constraint {
    margin: auto 0 !important;
  }
}

/* 修复导航栏与页面容器的间距问题 */
${this.currentPageType === GreasyForkPageType.USER_PROFILE
  ? `
${this.elementManager.selector.scriptNavigator} {
  /* 调整用户页面 */ 
  .width-constraint  {
    padding-top: ${AppStyleCollections.Module.SCRIPT_NAVIGATOR.height} !important;
  }
}
  `
  : `
${this.elementManager.selector.scriptNavigator} {
  /* 调整脚本列表、用户等页面 */ 
  .sidebarred {
    display: flex !important;
    align-items: baseline !important;

    .sidebarred-main-content, .width-constraint  {
      margin-top: ${AppStyleCollections.Module.SCRIPT_NAVIGATOR.height} !important;
    }
  }
} `}

/* 修复导航菜单栏与脚本导航栏的间距问题 */
${this.elementManager.selector.navbar} {
  ${AppStyleCollections.Module.SCRIPT_NAVIGATOR.selector} {
    margin-top: ${MODULE_CONFIG.COMPONENTS.navbar.height} !important;
  }
}
`
  }

  getMainStyles(_theme: ThemeType): string {
    // 通用样式
    const commonStyles = this.commonPage.getMainStyles()

    // 动态获取当前页面样式
    let pageStyles = ''
    const PageHandlerClass = PAGE_HANDLERS[this.currentPageType as GreasyForkPageType]
    if (PageHandlerClass) {
      pageStyles = PageHandlerClass.getInstance().getMainStyles()
    }

    return `
/* ===================== 通用样式 ===================== */   
${commonStyles}
/* ===================== 独立样式 ===================== */
${pageStyles}
`
  }

  getPatchedStyles(_theme: ThemeType): string {
    const { CONTENT_CONTAINER, RESULT_CONTAINER, HEADER_CONTAINER } = this.elements
    let pageStyles = ''

    switch (this.currentPageType) {
      case GreasyForkPageType.SCRIPT_LIST:
        pageStyles = this.scriptListPage.getPatchedStyles()
        break
    }

    return `
${CONTENT_CONTAINER?.selector} {
  width: ${AppStyleCollections.Module.SCRIPT_NAVIGATOR.width} !important;
  max-width: ${AppStyleCollections.Module.SCRIPT_NAVIGATOR.width} !important;
}   

${RESULT_CONTAINER?.selector} {
  border: none !important;
  box-shadow: none !important;
}

/* 隐藏页眉 */
${HEADER_CONTAINER?.selector} {
  display: none !important;
}

${pageStyles}
`
  }

  getFixedStyles(_theme: ThemeType): string {
    return ``
  }

  getComponentStyles(theme: ThemeType): string {
    return `
/* +++++++++++++++++ 3.5.1 预格式化文本样式 ++++++++++++++ */
${this.getPreStyles(theme)}
/* +++++++++++++++++ 3.5.2 代码块样式 ++++++++++++++++++++ */
${this.getCodeStyles(theme)}
/* +++++++++++++++++ 3.5.3 链接样式 ++++++++++++++++++++++ */
${this.getLinkStyles(theme)}
/* +++++++++++++++++ 3.5.4 表格样式 ++++++++++++++++++++++ */
${this.getTableStyles(theme)}
/* +++++++++++++++++ 3.5.5 水平分割线样式 ++++++++++++++++ */
${this.getHrStyles(theme)}
/* +++++++++++++++++ 3.5.6 引用块样式 ++++++++++++++++++++ */
${this.getBlockQuoteStyles(theme)}
/* +++++++++++++++++ 3.5.7 图片样式 ++++++++++++++++++++++ */
${this.getImageStyles(theme)}
  `
  }
}
